package tq.com.tqim.net;

import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import tq.com.extern.TQNetError;
import tq.com.tqim.config.TqConfig;

public class TQImHttpBase {

    static private String TAG = "TQImHttpBase";
    private OkHttpClient client = null;
    private int MAX_TIMEOUT = 60;

    static int RET_VALUE_SUCCESS = 0x00;

    static private TQImHttpBase gClient = new TQImHttpBase();
    static public TQImHttpBase client(){
        return gClient;
    }

    private Map<String, String> headers = new HashMap<>();

    public  TQImHttpBase(){
    }

    public void resetClient(){
        client = null;
    }
    private void checkClient(){
        if(client != null){
            return;
        }

        client = new OkHttpClient.Builder()
                .connectTimeout(MAX_TIMEOUT, TimeUnit.SECONDS)
//                .readTimeout(MAX_TIMEOUT, TimeUnit.SECONDS)
//                .writeTimeout(MAX_TIMEOUT, TimeUnit.SECONDS)
                .build();
    }


    //application/json
    public void post(String url, String content, TQImCallback callback){
        MediaType strType = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(strType, content);

        Request.Builder build = new Request.Builder()
                .url(fullUrl(url))
                .post(body);


        enqueueRequest(build, callback);
    }

    //application/x-www-urlencoded
    public void post(String url, Map<String, String> param, TQImCallback callback){
        FormBody.Builder body = mkForm(param);
        if(body == null){
            Log.d(TAG, "post no body");
            return;
        }

        Request.Builder build = new Request.Builder()
                .url(fullUrl(url))
                .post(body.build());

        enqueueRequest(build, callback);
    }

    public void get(String url, Map<String, String> param, TQImCallback callback){
        Request.Builder request = new Request.Builder()
                .url(fullUrl(url))
                .get();

        enqueueRequest(request, callback);
    }

    public void addHeader(String key, String value){
        if(key == null || value == null) return;
        synchronized (headers){
            if(headers.containsKey(key)){
                headers.remove(key);
            }

            headers.put(key, value);
        }

    }
    public void removeHeader(String key){
        if(key == null) return;
        synchronized (headers){
            headers.remove(key);
        }

    }

    private FormBody.Builder mkForm( Map<String, String> param){
        if(param == null || param.size() == 0) return null;
        FormBody.Builder builder = new FormBody.Builder();

        for (Map.Entry<String, String> item : param.entrySet()){
            builder.add(item.getKey(), item.getValue());
        }
        return builder;
    }

    private void mkHeader(Request.Builder builder){
        synchronized (headers){
            if(headers.size() == 0) return;

            for (Map.Entry<String, String> entry : headers.entrySet()){
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }

    }
    private void enqueueRequest(Request.Builder request, final TQImCallback callback){
        checkClient();
        mkHeader(request);

        Call call = client.newCall(request.build());
        call.enqueue(new okhttp3.Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
                if(callback != null){
                    callback.failed(new TQNetError(e.getLocalizedMessage()));
                }
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if(response.code() != 200){
                    if(callback != null){
                        callback.failed(new TQNetError(response.message()));
                    }
                    return;
                }

                String body = response.body().string();

                Log.d(TAG, String.format("body :: %s", body));
                try {
                    JSONObject jsonObject = new JSONObject(body);
                    int ret = jsonObject.optInt("ret");
                    if(ret == RET_VALUE_SUCCESS){
                        if(callback != null) callback.succes(jsonObject);
                    }else{
                        String msg = jsonObject.optString("err");
                        if(callback != null) callback.failed(new TQNetError(ret, msg));
                    }
                }catch (JSONException exception){
                    exception.printStackTrace();
                }
            }
        });
    }

    private String fullUrl(String url){
        String f = String.format("%s%s", TqConfig.instance().getBaseUrl(), url);
        Log.d(TAG, String.format("request url::: %s", f));
        return f;
    }

    private String formatUrlParam(Map<String, String> param){
        StringBuffer stringBuffer = new StringBuffer(1024);
        for (Map.Entry<String, String> entry : param.entrySet()){
            String item = String.format("%s=%s", entry.getKey(), entry.getValue());
            if(stringBuffer.length() >= 0){
                stringBuffer.append("&");
            }
            stringBuffer.append(item);
        }
        return stringBuffer.toString();
    }


}
